﻿using soma.Helpers;
using soma.Models;
using soma.Models.Resources;
using soma.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace soma.Controllers
{
    public class FlickrController : ApiController
    {
        private FlickrSearch flickrSearch;

        public FlickrController()
        {
            flickrSearch = new FlickrSearch();
        }

        [HttpPost]
        public HttpResponseMessage Post(Query query)
        {
            HttpResponseMessage responseMessage = new HttpResponseMessage();

            string errorMessage;
            if (!APIKeyVerifier.Instance.VerifyAPIKeyValidity(query.Key, out errorMessage))
            {
                responseMessage.StatusCode = HttpStatusCode.Forbidden;
                responseMessage.ReasonPhrase = errorMessage;
                return responseMessage;
            }

            if (query.Results <= 0)
            {
                responseMessage.StatusCode = HttpStatusCode.BadRequest;
                responseMessage.Content = new StringContent("The number of results must be greater than 0");
                return responseMessage;
            }

            List<Tag> tagList = TagsSplitter.SplitAndDistributeTags(query.Tags, query.Results);
            List<Tag> allWordsList = new List<Tag>();

            if (query.UseSynonyms)
            {
                // Get synonyms 
                foreach (Tag tag in tagList)
                {
                    int noSynonyms = (int)Math.Sqrt(tag.NumberResults);

                    if (noSynonyms == 0)
                    {
                        noSynonyms = 1;
                    }

                    List<string> synonymsForTag = SynonymsProvider.Instance.ProvideSynonyms(tag.TagName, noSynonyms);
                    foreach (string synonym in synonymsForTag)
                    {
                        tag.Synonyms.Add(new Tag(synonym, 0));
                    }
                }

                // Devide results between tags
                foreach (Tag tag in tagList)
                {
                    TagsSplitter.DivideResultBetweenTagAndSynonyms(tag);
                }
            }

            foreach (Tag tag in tagList)
            {
                allWordsList.Add(tag);
                allWordsList.AddRange(tag.Synonyms);
            }

            foreach (Tag tag in allWordsList)
            {
                // Verify if the time from when the last photo was uploaded and current time is bigger
                // than constant. If so, download new photos, if not, get from cache. If this is 
                // DateTime.MinValue no photo is present for that tag

                DateTime latestPhotoDateTime = PhotosRepository.Instance.GetDateTimeLatestResourceByTag(tag.TagName);
                List<PhotoResource> photoResourceList = null;

                if (latestPhotoDateTime.Equals(DateTime.MinValue) || latestPhotoDateTime < DateTime.Now.AddMinutes((-1) * Constants.MIN_DIFF_TIME_RESOURCES))
                {
                    // Get photos from flickr
                    photoResourceList = flickrSearch.SearchPhotosByTag(tag.TagName, tag.NumberResults, latestPhotoDateTime);
                    foreach (PhotoResource photoResource in photoResourceList)
                    {
                        if (!query.UseSynonyms)
                        {
                            photoResource.IsSynonym = false;
                        }
                        else
                        {
                            photoResource.IsSynonym = (tag.Synonyms.Count() == 0);
                        }
                    }
                    PhotosRepository.Instance.AddResourcesByTag(tag.TagName, photoResourceList.Cast<IResource>().ToList());
                }
                else
                {
                    // Get the photos from repository
                    photoResourceList = PhotosRepository.Instance.GetResourceByTag(tag.TagName, tag.NumberResults).Cast<PhotoResource>().ToList();
                }
            }

            responseMessage.StatusCode = HttpStatusCode.OK;
            return responseMessage;
        }
    }
}
